#ifndef PSFPhotonDetHit_h
#define PSFPhotonDetHit_h 1

#include "G4Allocator.hh"
#include "G4LogicalVolume.hh"
#include "G4THitsCollection.hh"
#include "G4ThreeVector.hh"
#include "G4VHit.hh"
#include "G4VPhysicalVolume.hh"

class PSFPhotonDetHit : public G4VHit
{
public:
  PSFPhotonDetHit();
  PSFPhotonDetHit(G4ThreeVector pExit, G4ThreeVector pArrive, G4double pTime, G4double pEnergy, G4int pDetNumber, G4ThreeVector pDirection);
  ~PSFPhotonDetHit() override = default;

  PSFPhotonDetHit(const PSFPhotonDetHit &right);
  const PSFPhotonDetHit &operator=(const PSFPhotonDetHit &right);

  G4bool operator==(const PSFPhotonDetHit &right) const;

  inline void *operator new(size_t);
  inline void operator delete(void *aHit);

  inline void SetArrivalPos(G4ThreeVector xyz) { fPosArrive = xyz; }
  inline G4ThreeVector GetArrivalPos() { return fPosArrive; }

  inline void SetExitPos(G4ThreeVector xyz) { fPosExit = xyz; }
  inline G4ThreeVector GetExitPos() { return fPosExit; }

  inline void SetArrivalTime(G4double t) { fArrivalTime = t; }
  inline G4double GetArrivalTime() { return fArrivalTime; }

  inline void SetEnergy(G4double en) { fEnergy = en; }
  inline G4double GetEnergy() { return fEnergy; }

  inline G4int GetDetNumber() { return fDetNumber; }
  ////////////////////////////////////////////////////////////////////////
  inline G4ThreeVector GetPosDir() { return fPosDirection; }

  void Print() override;

private:
  // the arrival time of the photon
  G4double fArrivalTime = 0.;
  // where the photon hit the detector (detector's coordinate)
  G4ThreeVector fPosArrive;
  // where the photon exited the fiber (world's coordinate)
  G4ThreeVector fPosExit;
  // energy of photon
  G4double fEnergy = 0.;
  // detector number
  G4int fDetNumber = 0;
  ////////////////////////////////////////////////////////////////////////
  // 光子到达探测器的方向
  G4ThreeVector fPosDirection;
};

//--------------------------------------------------
// Type Definitions
//--------------------------------------------------

typedef G4THitsCollection<PSFPhotonDetHit> PSFPhotonDetHitsCollection;

extern G4ThreadLocal G4Allocator<PSFPhotonDetHit> *PSFPhotonDetHitAllocator;

//--------------------------------------------------
// Operator Overloads
//--------------------------------------------------

inline void *PSFPhotonDetHit::operator new(size_t)
{
  if (!PSFPhotonDetHitAllocator)
    PSFPhotonDetHitAllocator = new G4Allocator<PSFPhotonDetHit>;
  return (void *)PSFPhotonDetHitAllocator->MallocSingle();
}

inline void PSFPhotonDetHit::operator delete(void *aHit)
{
  PSFPhotonDetHitAllocator->FreeSingle((PSFPhotonDetHit *)aHit);
}

#endif
